package com.xiaoc.bulldozer.controller;

import com.xc.framework.common.exception.BusinessException;
import com.xc.framework.common.thread.ThreadContext;
import com.xc.framework.web.FrontBaseController;
import com.xiaoc.bulldozer.common.Constant;
import com.xiaoc.bulldozer.common.ResponseCode;
import com.xiaoc.bulldozer.common.dto.WeixinUserDto;
import com.xiaoc.bulldozer.facade.WeixinUserFacade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import java.util.Map;

/**
 * @author wj
 */
public class BulldozerFrontBaseController extends FrontBaseController {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    protected void checkBindingResult(BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throwException(ResponseCode.PARAM_ERROR);
        }
    }

    protected void throwException(ResponseCode responseCode){
        throw new BusinessException(responseCode.getCode(), responseCode.getMsg());
    }

    public static final String CODE = "code";
    public static final String MSG = "msg";

    @Resource(name = "weixinUserFacade")
    private WeixinUserFacade weixinUserFacade;

    @ExceptionHandler(Exception.class)
    public ModelAndView handleAllException(Exception e) {
        logger.error("system exception", e);
        int code = ResponseCode.BUSINESS_ERROR.getCode();
        String msg = ResponseCode.BUSINESS_ERROR.getMsg();
        if (e instanceof BusinessException) {
            code = ((BusinessException) e).getErrorCode();
            msg = e.getMessage();
        }
        return jsonFailed(code, msg);
    }

    public String getCurrentSessionId() {
        return (String) ThreadContext.get(Constant.COOKIE_SESSION_ID);
    }

    public WeixinUserDto getCurrentWeixinUserDto() {
        return weixinUserFacade.getWeixinUserDtoBySessionId(getCurrentSessionId());
    }

    @Override
    public ModelAndView renderJson(String template, Map<String, Object> params) {

        ModelAndView mav = buildModelAndView(template);

        WeixinUserDto weixinUserDto = getCurrentWeixinUserDto();
        putCookieInfo(weixinUserDto, params);

        mav.addAllObjects(params);
        return mav;
    }

    private ModelAndView buildModelAndView(String template) {
        ModelAndView mav = new ModelAndView(template);

        if (mav.getModel().get(CODE) == null) {
            mav.getModel().put(CODE, 200);
        }

        if (mav.getModel().get(MSG) == null) {
            mav.getModel().put(MSG, "OK");
        }
        return mav;
    }

    @Override
    public ModelAndView jsonSucess() {

        ModelAndView mav = new ModelAndView("common/success.json");

        WeixinUserDto weixinUserDto = getCurrentWeixinUserDto();
        putCookieInfo(weixinUserDto, mav.getModel());
        return mav;
    }

    @Override
    public ModelAndView jsonFailed(int code, String msg) {
        WeixinUserDto weixinUserDto = getCurrentWeixinUserDto();
        ModelAndView mav = new ModelAndView("common/failed.json");
        mav.getModel().put(CODE, code);
        mav.getModel().put(MSG, msg);
        putCookieInfo(weixinUserDto, mav.getModel());
        return mav;
    }

    public ModelAndView jsonFailed(ResponseCode responseCode) {
        ModelAndView mav = new ModelAndView("common/failed.json");
        mav.getModel().put(CODE, responseCode.getCode());
        mav.getModel().put(MSG, responseCode.getMsg());
        putCookieInfo(getCurrentWeixinUserDto(), mav.getModel());
        return mav;
    }

    private void putCookieInfo(WeixinUserDto weixinUserDto, Map<String, Object> model) {
        model.put(Constant.COOKIE_SESSION_ID, getCurrentSessionId());
        model.put(Constant.COOKIE_SESSION_USERTYPE, weixinUserDto == null ? 0 : weixinUserDto.getUserType());
    }


    public ModelAndView renderLoginJson(String template, Map<String, Object> params) {
        ModelAndView mav = buildModelAndView(template);
        mav.addAllObjects(params);
        return mav;
    }

    public ModelAndView renderHttp(String template, Map<String, Object> params) {

        ModelAndView mav = buildModelAndView(template);
        mav.addAllObjects(params);
        return mav;

    }

}
